package com.j4dream.property.javabasic.collection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;

public class ListNote {
    private void arrayListElementData() {
        // 使用 elementData 保存数据
        // transient Object[] elementData;
        // transient用来表示一个域不是该对象序行化的一部分，当一个对象被序行化的时候，transient修饰的变量的值是不包括在序行化的表示中的。
        // 但是ArrayList又是可序行化的类，elementData是ArrayList具体存放元素的成员，用transient来修饰elementData，岂不是反序列化
        // 后的ArrayList丢失了原先的元素？
        // arrayList在序列化的时候会调用writeObject，直接将size和element写入ObjectOutputStream；反序列化时调用readObject，
        // 从ObjectInputStream获取size和element，再恢复到elementData。
        // 为什么不直接用elementData来序列化，而采用上诉的方式来实现序列化呢？原因在于elementData是一个缓存数组，它通常会预留一些容量，
        // 等容量不足时再扩充容量，那么有些空间可能就没有实际存储元素，采用上诉的方式来实现序列化时，就可以保证只序列化实际存储的那些元素，
        // 而不是整个数组，从而节省空间和时间。
        ArrayList arrayList1 = new ArrayList();

        // ensureCapacityInternal 默认 10 大小， if (minCapacity - elementData.length > 0) grow(minCapacity);
        // 增长 为原来的 50%， 10 + 5：int newCapacity = oldCapacity + (oldCapacity >> 1)
        // 复制数组 elementData = Arrays.copyOf(elementData, newCapacity);
        // modCount 属性可以判断多线程情况下有无问题 writeObject....
        arrayList1.add(1);
    }

    private void vectorTraining() {
        // vector 方法加了 synchronized 修饰，线程同步， protected Object[] elementData 保存数据。
        Vector vector1 = new Vector();
        //  int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
        //                    capacityIncrement : oldCapacity);
        // 默认增长为原来的 100%； ArrayList 默认有 DEFAULT_CAPACITY，而 Vector 没有
        vector1.add(1);
    }

    private void LinkedListTraining() {
        // linkedlist 基于双链表实现
        LinkedList linkedList1 = new LinkedList();
        // add 默认 调用 linkLast 方法，last 元素保存尾元素，添加元素后，last 改变。
        linkedList1.add(1);

        // 同样调用 linkLast 方法
        linkedList1.addLast(10);

        // linkFirst 方法
        linkedList1.addFirst(-1);

        linkedList1.add(2);

        linkedList1.get(3);

        // 同时实现了 Deque 接口
        // 作为栈使用
        LinkedList stack = new LinkedList();
        stack.push(1);
        stack.push(2);

        // 2
        stack.pop();

        // 作为队列使用
        LinkedList queue = new LinkedList();
        queue.offer(1);
        queue.offer(2);

        // 1
        queue.poll();

        Iterator it = linkedList1.listIterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
